using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
using ContentRenderingApi;
using ContentRenderingApiSystemTest.Helper;
using ContentRenderingApi.Path;
using ContentRenderingApi.Extender;
using System;

namespace ContentRenderingApiSystemTest.TestFixture
{
    [TestFixture]
    public class RenderSortTestFixture
    {
        [Test]
        public void SelfSortTest()
        {
            AbstractTemplate template = new EmbeddedResourceTemplate(
                Assembly.GetExecutingAssembly(),
                "ContentRenderingApiSystemTest.TestFixture.Input",
                "SelfSort");

            template.AddNamedParameter("testone", "zzz");
            template.AddNamedParameter("testone", "aaa");
            template.AddNamedParameter("testone", "sss");

            ObjectIndexerHelper testTwoIndexer = new ObjectIndexerHelper(
                "testtwob",
                new string[] { "a123", "z123", "s123" });

            template.AddNamedParameter("testtwoa", testTwoIndexer);

            ObjectIndexerHelper testThreeIndexer = new ObjectIndexerHelper(
                "testthreec",
                new int[] { 14,3,9,4 });

            template.AddNamedParameter("testthreea", new ObjectIndexerHelper("testthreeb", testThreeIndexer));

            template.TransformationConfiguration.AddSelfSort<string>(new FullPath("testone"), (left, right) => string.Compare((string)left, (string)right));
            template.TransformationConfiguration.AddSelfSort<string>(new FullPath("testtwoa", "testtwob"), (left, right) => string.Compare((string)left, (string)right));
            template.TransformationConfiguration.AddSelfSort<int>(new FullPath("testthreea", "testthreeb", "testthreec"), (left,right) => (int)left - (int)right);

            Assert.AreEqual(
                ResourceHelper.FetchString("ContentRenderingApiSystemTest.TestFixture.Output.SelfSort.txt"),
                template.Render());
        }

        [Test]
        public void SelfSortChainTest()
        {
            AbstractTemplate template = new EmbeddedResourceTemplate(
                Assembly.GetExecutingAssembly(),
                "ContentRenderingApiSystemTest.TestFixture.Input",
                "SelfSortChain");

            template.AddNamedParameter("testone", "zzz");
            template.AddNamedParameter("testone", 3);
            template.AddNamedParameter("testone", "aaa");
            template.AddNamedParameter("testone", 2);
            template.AddNamedParameter("testone", 6);
            template.AddNamedParameter("testone", "sss");

            template.TransformationConfiguration.AddSelfSort<string>(new FullPath("testone"), (left, right) => string.Compare((string)left, (string)right));
            template.TransformationConfiguration.AddSelfSort<int>(new FullPath("testone"), (left, right) => (int)left - (int)right);

            Assert.AreEqual(
                ResourceHelper.FetchString("ContentRenderingApiSystemTest.TestFixture.Output.SelfSortChain.txt"),
                template.Render());
        }

        [Test]
        public void ChildSortOneTest()
        {
            AbstractTemplate template = new EmbeddedResourceTemplate(
                Assembly.GetExecutingAssembly(),
                "ContentRenderingApiSystemTest.TestFixture.Input",
                "ChildSortOne");

            Dictionary<string, object>[] testChilds = new Dictionary<string, object>[5];

            // set parameters
            testChilds[0] = new Dictionary<string, object>();
            testChilds[0].Add("testchildone", "ZZZ");
            testChilds[0].Add("testchildtwo", "XXX");
            testChilds[0].Add("testchildthree", "YYY");

            // set parameters
            testChilds[1] = new Dictionary<string, object>();
            testChilds[1].Add("testchildone", "AAA");
            testChilds[1].Add("testchildtwo", "BBB");
            testChilds[1].Add("testchildthree", "CCC");

            // set parameters
            testChilds[2] = new Dictionary<string, object>();
            testChilds[2].Add("testchildone", "VVV");
            testChilds[2].Add("testchildtwo", 11111);
            testChilds[2].Add("testchildthree", "GGG");

            // set parameters
            testChilds[3] = new Dictionary<string, object>();
            testChilds[3].Add("testchildone", "123");
            testChilds[3].Add("testchildthree", "456");

            // set parameters
            testChilds[4] = new Dictionary<string, object>();
            testChilds[4].Add("testchildone", "DDD");
            testChilds[4].Add("testchildtwo", "FFF");
            testChilds[4].Add("testchildthree", "AAA");

            template.AddNamedParameter("testone", testChilds);
            
            template.TransformationConfiguration.AddChildSort(new FullPath("testone"), (left, right) => string.Compare((string)left[0], (string)right[0]), new NameTypeExtender("testchildtwo", typeof(string)));

            Assert.AreEqual(
                ResourceHelper.FetchString("ContentRenderingApiSystemTest.TestFixture.Output.ChildSortOne.txt"),
                template.Render());
        }

        [Test]
        public void ChildSortTwoTest()
        {
            Func<object[], object[], int> callback = delegate(object[] valuesOne, object[] valuesTwo)
            {
                int first = string.Compare((string)valuesOne[0], (string)valuesTwo[0]);

                if (first != 0)
                {
                    return first;
                }

                int second = (int)valuesOne[1] - (int)valuesTwo[1];

                if (second != 0)
                {
                    return second;
                }

                return string.Compare((string)valuesOne[2], (string)valuesTwo[2]);
            };
            
            AbstractTemplate template = new EmbeddedResourceTemplate(
                Assembly.GetExecutingAssembly(),
                "ContentRenderingApiSystemTest.TestFixture.Input",
                "ChildSortTwo");

            Dictionary<string, object>[] testChilds = new Dictionary<string, object>[5];

            // set parameters
            testChilds[0] = new Dictionary<string, object>();
            testChilds[0].Add("testchildone", 888);
            testChilds[0].Add("testchildtwo", "XXX");
            testChilds[0].Add("testchildthree", "YYY");

            // set parameters
            testChilds[1] = new Dictionary<string, object>();
            testChilds[1].Add("testchildone", 1);
            testChilds[1].Add("testchildtwo", "XXX");
            testChilds[1].Add("testchildthree", "CCC");

            // set parameters
            testChilds[2] = new Dictionary<string, object>();
            testChilds[2].Add("testchildone", "VVV");
            testChilds[2].Add("testchildtwo", 11111);
            testChilds[2].Add("testchildthree", "GGG");

            // set parameters
            testChilds[3] = new Dictionary<string, object>();
            testChilds[3].Add("testchildone", 123);
            testChilds[3].Add("testchildthree", "456");

            // set parameters
            testChilds[4] = new Dictionary<string, object>();
            testChilds[4].Add("testchildone", "DDD");
            testChilds[4].Add("testchildtwo", "XXX");
            testChilds[4].Add("testchildthree", "AAA");

            template.AddNamedParameter("testone", testChilds);

            template.TransformationConfiguration.AddChildSort(new FullPath("testone"), callback, new NameTypeExtender("testchildtwo", typeof(string)), new NameTypeExtender("testchildone", typeof(int)), new NameTypeExtender("testchildthree", typeof(string)));

            Assert.AreEqual(
                ResourceHelper.FetchString("ContentRenderingApiSystemTest.TestFixture.Output.ChildSortTwo.txt"),
                template.Render());
        }

        [Test]
        public void ChildSortChainTest()
        {
            AbstractTemplate template = new EmbeddedResourceTemplate(
                Assembly.GetExecutingAssembly(),
                "ContentRenderingApiSystemTest.TestFixture.Input",
                "ChildSortChain");

            Dictionary<string, object>[] testChilds = new Dictionary<string, object>[5];

            // set parameters
            testChilds[0] = new Dictionary<string, object>();
            testChilds[0].Add("testchildone", 888);
            testChilds[0].Add("testchildtwo", "XXX");
            testChilds[0].Add("testchildthree", "YYY");

            // set parameters
            testChilds[1] = new Dictionary<string, object>();
            testChilds[1].Add("testchildone", 1);
            testChilds[1].Add("testchildtwo", "XXX");
            testChilds[1].Add("testchildthree", "CCC");

            // set parameters
            testChilds[2] = new Dictionary<string, object>();
            testChilds[2].Add("testchildone", "VVV");
            testChilds[2].Add("testchildtwo", 11111);
            testChilds[2].Add("testchildthree", "GGG");

            // set parameters
            testChilds[3] = new Dictionary<string, object>();
            testChilds[3].Add("testchildone", 123);
            testChilds[3].Add("testchildthree", "456");

            // set parameters
            testChilds[4] = new Dictionary<string, object>();
            testChilds[4].Add("testchildone", "DDD");
            testChilds[4].Add("testchildtwo", "XXX");
            testChilds[4].Add("testchildthree", "AAA");

            template.AddNamedParameter("testone", testChilds);

            template.TransformationConfiguration.AddChildSort(new FullPath("testone"), (left, right) => string.Compare((string)left[0], (string)right[0]), new NameTypeExtender("testchildtwo", typeof(string)));
            template.TransformationConfiguration.AddChildSort(new FullPath("testone"), (left, right) => (int)left[0] - (int)right[0], new NameTypeExtender("testchildone", typeof(int)));

            Assert.AreEqual(
                ResourceHelper.FetchString("ContentRenderingApiSystemTest.TestFixture.Output.ChildSortChain.txt"),
                template.Render());
        }
    }
}
